/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * IntersectionTester.java
 *
 * Created on 06/10/2010, 4:56:36 PM
 */

package Traffic;

import javax.swing.JSlider;
import javax.swing.JSpinner;

public class TrafficSimulator extends javax.swing.JFrame {

    //Thread for refreshing the visualisation
    private class RedrawThread extends Thread
    {
        public void run()
        {
            while(true)
            {
                itv.repaint();
                try{
                    Thread.sleep(50);
                }catch(Exception e){
                    e.printStackTrace();}
            }
        }
    }

    //Thread for running cycles
    private class CycleThread extends Thread
    {
        boolean run = true;
        public void run()
        {
            run = true;
            
            while(run)
            {
                if (m != null)
                {
                    m.runCycle();
                    try{
                        Thread.sleep(50);
                    }catch(Exception e){
                        e.printStackTrace();}
                }
            }
        }
    }

    Model m;
    TrafficSimulatorVisualisationPanel itv;
    RedrawThread redrawThread;
    CycleThread simulatorThread;

    /** Creates new form IntersectionTester */
    public TrafficSimulator() {
        initComponents();
        itv = (TrafficSimulatorVisualisationPanel) displayPanel;
        redrawThread = new RedrawThread();
        redrawThread.start();
    }

    public void runCycle()
    {
        m.runCycle();
        itv.repaint();
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        lblNProb = new javax.swing.JLabel();
        lblSProb = new javax.swing.JLabel();
        lblEProb = new javax.swing.JLabel();
        lblWProb = new javax.swing.JLabel();
        spnNLanes = new javax.swing.JSpinner();
        spnSLanes = new javax.swing.JSpinner();
        spnELanes = new javax.swing.JSpinner();
        spnWLanes = new javax.swing.JSpinner();
        sldNProb = new javax.swing.JSlider();
        sldSProb = new javax.swing.JSlider();
        sldEProb = new javax.swing.JSlider();
        sldWProb = new javax.swing.JSlider();
        jPanel2 = new javax.swing.JPanel();
        jLabel7 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        cmbEWSpeed = new javax.swing.JComboBox();
        cmbNSSpeed = new javax.swing.JComboBox();
        jPanel3 = new javax.swing.JPanel();
        jLabel8 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        spnNSTime = new javax.swing.JSpinner();
        spnNSTurnTime = new javax.swing.JSpinner();
        spnEWTime = new javax.swing.JSpinner();
        spnEWTurnTime = new javax.swing.JSpinner();
        jLabel14 = new javax.swing.JLabel();
        jPanel4 = new javax.swing.JPanel();
        jLabel16 = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        jLabel18 = new javax.swing.JLabel();
        jLabel19 = new javax.swing.JLabel();
        sldSlowChance = new javax.swing.JSlider();
        sldRegChance = new javax.swing.JSlider();
        sldImpatientChance = new javax.swing.JSlider();
        lblSlowChance = new javax.swing.JLabel();
        lblRegularChance = new javax.swing.JLabel();
        lblImpatientChance = new javax.swing.JLabel();
        lblBreakdownChance = new javax.swing.JLabel();
        sldBreakdownChance = new javax.swing.JSlider();
        jLabel25 = new javax.swing.JLabel();
        jPanel5 = new javax.swing.JPanel();
        btnRun = new javax.swing.JToggleButton();
        btnNew = new javax.swing.JButton();
        displayPanel = new TrafficSimulatorVisualisationPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("LaneSettings"));
        jPanel1.setLayout(new java.awt.GridBagLayout());

        jLabel1.setText("North");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 0);
        jPanel1.add(jLabel1, gridBagConstraints);

        jLabel2.setText("South");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(jLabel2, gridBagConstraints);

        jLabel3.setText("East");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(jLabel3, gridBagConstraints);

        jLabel4.setText("West");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(jLabel4, gridBagConstraints);

        jLabel5.setText("Lanes");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
        jPanel1.add(jLabel5, gridBagConstraints);

        jLabel6.setText("Vehicle Frequency");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(jLabel6, gridBagConstraints);

        lblNProb.setText("50");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 7;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(lblNProb, gridBagConstraints);

        lblSProb.setText("50");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 7;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(lblSProb, gridBagConstraints);

        lblEProb.setText("50");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.ipadx = 7;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(lblEProb, gridBagConstraints);

        lblWProb.setText("50");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.ipadx = 7;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(lblWProb, gridBagConstraints);

        spnNLanes.setValue(1);
        spnNLanes.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spnNLanesStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
        jPanel1.add(spnNLanes, gridBagConstraints);

        spnSLanes.setValue(1);
        spnSLanes.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spnNLanesStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 0);
        jPanel1.add(spnSLanes, gridBagConstraints);

        spnELanes.setValue(1);
        spnELanes.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spnELanesStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 0);
        jPanel1.add(spnELanes, gridBagConstraints);

        spnWLanes.setValue(1);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 0);
        jPanel1.add(spnWLanes, gridBagConstraints);

        sldNProb.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldNProbStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 180;
        jPanel1.add(sldNProb, gridBagConstraints);

        sldSProb.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldSProbStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 180;
        jPanel1.add(sldSProb, gridBagConstraints);

        sldEProb.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldEProbStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.ipadx = 180;
        jPanel1.add(sldEProb, gridBagConstraints);

        sldWProb.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldWProbStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.ipadx = 180;
        jPanel1.add(sldWProb, gridBagConstraints);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Speeds"));
        jPanel2.setLayout(new java.awt.GridBagLayout());

        jLabel7.setText("North/South");
        jPanel2.add(jLabel7, new java.awt.GridBagConstraints());

        jLabel9.setText("East/West");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        jPanel2.add(jLabel9, gridBagConstraints);

        cmbEWSpeed.setModel(new javax.swing.DefaultComboBoxModel(new Integer[] { 40, 50, 60, 70, 80 }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 12);
        jPanel2.add(cmbEWSpeed, gridBagConstraints);

        cmbNSSpeed.setModel(new javax.swing.DefaultComboBoxModel(new Integer[] { 40, 50, 60, 70, 80 }));
        cmbNSSpeed.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmbNSSpeedActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(0, 9, 0, 9);
        jPanel2.add(cmbNSSpeed, gridBagConstraints);

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Light Duration"));
        jPanel3.setLayout(new java.awt.GridBagLayout());

        jLabel8.setText("North/South");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel3.add(jLabel8, gridBagConstraints);

        jLabel10.setText("East/West");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel3.add(jLabel10, gridBagConstraints);

        jLabel11.setText("N/S Turning");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel3.add(jLabel11, gridBagConstraints);

        jLabel12.setText("Time");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 7, 0, 7);
        jPanel3.add(jLabel12, gridBagConstraints);

        jLabel13.setText("E/W Turning");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel3.add(jLabel13, gridBagConstraints);

        spnNSTime.setValue(20);
        spnNSTime.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spnNSTimeStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 12;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 6, 3, 6);
        jPanel3.add(spnNSTime, gridBagConstraints);

        spnNSTurnTime.setValue(20);
        spnNSTurnTime.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spnNSTimeStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 12;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 6, 3, 6);
        jPanel3.add(spnNSTurnTime, gridBagConstraints);

        spnEWTime.setValue(20);
        spnEWTime.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spnNSTimeStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 12;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 6, 3, 6);
        jPanel3.add(spnEWTime, gridBagConstraints);

        spnEWTurnTime.setValue(20);
        spnEWTurnTime.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spnNSTimeStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 12;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 6, 3, 6);
        jPanel3.add(spnEWTurnTime, gridBagConstraints);

        jLabel14.setText("Time");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
        jPanel3.add(jLabel14, gridBagConstraints);

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Frequencies"));
        jPanel4.setLayout(new java.awt.GridBagLayout());

        jLabel16.setText("Breakdowns");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel4.add(jLabel16, gridBagConstraints);

        jLabel17.setText("Slower Driver");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel4.add(jLabel17, gridBagConstraints);

        jLabel18.setText("Regular Driver");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel4.add(jLabel18, gridBagConstraints);

        jLabel19.setText("Impatient Driver");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel4.add(jLabel19, gridBagConstraints);

        sldSlowChance.setValue(33);
        sldSlowChance.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldSlowChanceStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 16;
        jPanel4.add(sldSlowChance, gridBagConstraints);

        sldRegChance.setMinimum(1);
        sldRegChance.setValue(33);
        sldRegChance.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldSlowChanceStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.ipadx = 16;
        jPanel4.add(sldRegChance, gridBagConstraints);

        sldImpatientChance.setValue(34);
        sldImpatientChance.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldSlowChanceStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.ipadx = 16;
        jPanel4.add(sldImpatientChance, gridBagConstraints);

        lblSlowChance.setText("33%");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
        jPanel4.add(lblSlowChance, gridBagConstraints);

        lblRegularChance.setText("33%");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
        jPanel4.add(lblRegularChance, gridBagConstraints);

        lblImpatientChance.setText("34%");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
        jPanel4.add(lblImpatientChance, gridBagConstraints);

        lblBreakdownChance.setText("50");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0);
        jPanel4.add(lblBreakdownChance, gridBagConstraints);

        sldBreakdownChance.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldBreakdownChanceStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.ipadx = 16;
        jPanel4.add(sldBreakdownChance, gridBagConstraints);

        jLabel25.setText(" ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        jPanel4.add(jLabel25, gridBagConstraints);

        jPanel5.setLayout(new java.awt.GridBagLayout());

        btnRun.setText("Start/Stop");
        btnRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRunActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipadx = 74;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
        jPanel5.add(btnRun, gridBagConstraints);

        btnNew.setText("New Simulation");
        btnNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNewActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        jPanel5.add(btnNew, gridBagConstraints);

        displayPanel.setMinimumSize(new java.awt.Dimension(600, 600));
        displayPanel.setPreferredSize(new java.awt.Dimension(600, 600));

        javax.swing.GroupLayout displayPanelLayout = new javax.swing.GroupLayout(displayPanel);
        displayPanel.setLayout(displayPanelLayout);
        displayPanelLayout.setHorizontalGroup(
            displayPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 600, Short.MAX_VALUE)
        );
        displayPanelLayout.setVerticalGroup(
            displayPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 600, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jPanel5, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 235, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(displayPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(11, 11, 11)
                        .addComponent(displayPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cmbNSSpeedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmbNSSpeedActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_cmbNSSpeedActionPerformed

    ///Event Handler for the new simulation button
    private void btnNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewActionPerformed
        //First we have to copy the settings over
        //Lane settings
        Settings.northLanes = (Integer)spnNLanes.getValue();
        Settings.southLanes = (Integer)spnSLanes.getValue();
        Settings.eastLanes = (Integer) spnELanes.getValue();
        Settings.westLanes = (Integer) spnWLanes.getValue();
        Settings.northChance = sldNProb.getValue();
        Settings.southChance = sldSProb.getValue();
        Settings.eastChance = sldEProb.getValue();
        Settings.westChance = sldWProb.getValue();

        //Speed
        Settings.northSouthSpeed = (Integer)cmbNSSpeed.getSelectedItem();
        Settings.eastWestSpeed = (Integer) cmbEWSpeed.getSelectedItem();

        //Lights
        Settings.timeNS = (Integer) spnNSTime.getValue();
        Settings.timeEW = (Integer) spnEWTime.getValue();
        Settings.timeNSTurn = (Integer) spnNSTurnTime.getValue();
        Settings.timeEWTurn = (Integer) spnEWTurnTime.getValue();

        //Breakdown prob
        Settings.breakdownChance = sldBreakdownChance.getValue();

        //Driver Types
        Settings.slow = sldSlowChance.getValue();
        Settings.normal = sldRegChance.getValue();
        Settings.fast = sldImpatientChance.getValue();

        


        m = new Model();
        itv = (TrafficSimulatorVisualisationPanel) displayPanel;
        itv.setView(m.getView());
    }//GEN-LAST:event_btnNewActionPerformed

    //Shared event handler for north and south lanes spinners
    private void spnNLanesStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNLanesStateChanged
        JSpinner source = (JSpinner)evt.getSource();

        //If the user has tried to set the number too low
        if ((Integer)source.getValue() < 1)
        {
            //Force it to the minimum allowable value
            source.setValue(1);
        }
        //Else if they have tried to set it too high
        else if (((Integer) spnNLanes.getValue() + (Integer) spnSLanes.getValue()) > Settings.MAX_LANES)
        {
            //Undo their change
            source.setValue((Integer) source.getValue() - 1);
        }
    }//GEN-LAST:event_spnNLanesStateChanged
    //Shared event handler for the east and west lanes spinner
    private void spnELanesStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnELanesStateChanged
        JSpinner source = (JSpinner)evt.getSource();

        //If the user has tried to set the number too low
        if ((Integer)source.getValue() < 1)
        {
            //Force it to the minimum allowable value
            source.setValue(1);
        }
        //Else if they have tried to set it too high
        else if (((Integer) spnELanes.getValue() + (Integer) spnWLanes.getValue()) > Settings.MAX_LANES)
        {
            //Undo their change
            source.setValue((Integer) source.getValue() - 1);
        }
    }//GEN-LAST:event_spnELanesStateChanged

    private void sldNProbStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldNProbStateChanged
        lblNProb.setText("" + sldNProb.getValue());
    }//GEN-LAST:event_sldNProbStateChanged

    private void sldSProbStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldSProbStateChanged
        lblSProb.setText("" + sldSProb.getValue());
    }//GEN-LAST:event_sldSProbStateChanged

    private void sldEProbStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldEProbStateChanged
        lblEProb.setText("" + sldEProb.getValue());
    }//GEN-LAST:event_sldEProbStateChanged

    private void sldWProbStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldWProbStateChanged
        lblWProb.setText("" + sldWProb.getValue());
    }//GEN-LAST:event_sldWProbStateChanged

    //Shared Event Handler for all green light time spinners
    private void spnNSTimeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNSTimeStateChanged
        JSpinner source = (JSpinner) evt.getSource();

        //If the value has been set too low
        if ((Integer) source.getValue() < 20)
        {
            //Force it to an acceptible value
            source.setValue(20);
        }
    }//GEN-LAST:event_spnNSTimeStateChanged

    private void sldBreakdownChanceStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldBreakdownChanceStateChanged
        lblBreakdownChance.setText("" + sldBreakdownChance.getValue());
    }//GEN-LAST:event_sldBreakdownChanceStateChanged

    //Event Handler for all of the driver chance sliders
    private void sldSlowChanceStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldSlowChanceStateChanged
        //Wait until the user has finished adjusting the value
        JSlider source = (JSlider) evt.getSource();
        if (!source.getValueIsAdjusting())
        {
            float total = sldSlowChance.getValue() + sldRegChance.getValue() + sldImpatientChance.getValue();
            int slow, regular, fast;
            slow = (int)((sldSlowChance.getValue() / total) * 100);
            regular = (int)((sldRegChance.getValue() / total) * 100);
            fast = (int)((sldImpatientChance.getValue() / total) * 100);
            lblSlowChance.setText(slow + "%");
            lblRegularChance.setText(regular + "%");
            lblImpatientChance.setText(fast + "%");
        }
    }//GEN-LAST:event_sldSlowChanceStateChanged

    //Event Handler for the start/stop toggle button
    private void btnRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRunActionPerformed
        //We can't run if there is no model set up yet
        if (m != null)
        {
            //If the button is down
            if (btnRun.isSelected())
            {
                //Start running cycles
                simulatorThread = new CycleThread();
                simulatorThread.start();
            }
            //If it is up
            else
            {
                //Stop the thread
                simulatorThread.run = false;
            }
        }
    }//GEN-LAST:event_btnRunActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TrafficSimulator().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnNew;
    private javax.swing.JToggleButton btnRun;
    private javax.swing.JComboBox cmbEWSpeed;
    private javax.swing.JComboBox cmbNSSpeed;
    private javax.swing.JPanel displayPanel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel25;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JLabel lblBreakdownChance;
    private javax.swing.JLabel lblEProb;
    private javax.swing.JLabel lblImpatientChance;
    private javax.swing.JLabel lblNProb;
    private javax.swing.JLabel lblRegularChance;
    private javax.swing.JLabel lblSProb;
    private javax.swing.JLabel lblSlowChance;
    private javax.swing.JLabel lblWProb;
    private javax.swing.JSlider sldBreakdownChance;
    private javax.swing.JSlider sldEProb;
    private javax.swing.JSlider sldImpatientChance;
    private javax.swing.JSlider sldNProb;
    private javax.swing.JSlider sldRegChance;
    private javax.swing.JSlider sldSProb;
    private javax.swing.JSlider sldSlowChance;
    private javax.swing.JSlider sldWProb;
    private javax.swing.JSpinner spnELanes;
    private javax.swing.JSpinner spnEWTime;
    private javax.swing.JSpinner spnEWTurnTime;
    private javax.swing.JSpinner spnNLanes;
    private javax.swing.JSpinner spnNSTime;
    private javax.swing.JSpinner spnNSTurnTime;
    private javax.swing.JSpinner spnSLanes;
    private javax.swing.JSpinner spnWLanes;
    // End of variables declaration//GEN-END:variables

}
